package com.xdhl.fu.fim.xxljob.job;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xdhl.fu.common.core.constant.flightinfo.FlightInfoConstants;
import com.xdhl.fu.common.core.task.IJob;
import com.xdhl.fu.fim.service.IFlightInfoConfigService;
import com.xdhl.fu.flight.info.api.domain.FlightInfoConfig;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.LocalDateTime;

/**
 * 国际原油价格更新器
 * 用于根据消息事件从网络上获取最新的布伦特国际原油价格，然后存入数据库。
 *
 * @author 朱力维
 * @time 2022/6/2 14:46
 */
@Component
public class BrentCrudeUpdateJob implements IJob {

    private static final Logger log = LoggerFactory.getLogger(BrentCrudeUpdateJob.class);

    public static final String TARGET_URL = "https://info.usd-cny.com/data/oil.js";

    @Value("${spring.application.name}")
    private String applicationName;

    @Resource
    private IFlightInfoConfigService flightInfoConfigService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    public static void main(String[] args) {
        // 静态方法获取客户端HttpClient
        HttpClient httpClient = HttpClient.newHttpClient();
        // 静态方法创建
        HttpRequest request = HttpRequest.newBuilder(URI.create(TARGET_URL)).build();
        // 生成BodyHandler
        HttpResponse.BodyHandler<String> responseBodyHandler = HttpResponse.BodyHandlers.ofString();
        // 发送 得到HttpResponse
        try {
            // 获取布伦特原油价格js并解析出原油
            HttpResponse<String> response = httpClient.send(request, responseBodyHandler);
            String body = response.body();
            String[] lines = body.split("\n");
            String line = lines[1];
            String doubleQuotationMark = "\"";
            String price = line.substring(line.indexOf(doubleQuotationMark) + 1, line.lastIndexOf(doubleQuotationMark));
            System.out.println(price.split(",")[0]);
        } catch (Exception e) {
        }
    }

    @Transactional
    @XxlJob(value = "brentCrudeUpdateJob", init = "init", destroy = "destroy")
    public ReturnT<String> execute(String param) {
        this.start();
        log.info("布伦特国际原油价格已更新完成。");
        return ReturnT.SUCCESS;
    }

    @Override
    public void start() {
        LambdaQueryWrapper<FlightInfoConfig> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FlightInfoConfig::getConfigKey, FlightInfoConstants.BRENT_CRUDE_PRICE_CONFIG_NAME);
        FlightInfoConfig config = flightInfoConfigService.getOne(wrapper);
        if (config == null) {
            config = new FlightInfoConfig();
            config.setConfigName("布伦特国际原油价格");
            config.setConfigKey(FlightInfoConstants.BRENT_CRUDE_PRICE_CONFIG_NAME);
            config.setRemark(config.getConfigName());
            config.setCreateBy(applicationName);
            config.setCreateTime(LocalDateTime.now());
        }

        Double price = getPrice();
        config.setConfigValue(price.toString());
        config.setUpdateBy(applicationName);
        config.setUpdateTime(LocalDateTime.now());
        flightInfoConfigService.saveOrUpdate(config);
        stringRedisTemplate.opsForValue().set(FlightInfoConstants.BRENT_CRUDE_PRICE_CONFIG_NAME, price.toString().trim());
    }

    @Override
    public void init() {

    }

    @Override
    public void destroy() {

    }

    /**
     * 获取布伦特国际原油价格
     *
     * @return 布伦特国际原油价格
     */
    private Double getPrice() {
        Double price = 0D;
        // 静态方法获取客户端HttpClient
        HttpClient httpClient = HttpClient.newHttpClient();
        // 静态方法创建
        HttpRequest request = HttpRequest.newBuilder(URI.create(TARGET_URL)).build();
        // 生成BodyHandler
        HttpResponse.BodyHandler<String> responseBodyHandler = HttpResponse.BodyHandlers.ofString();
        try {
            // 获取布伦特原油价格js并解析出原油
            HttpResponse<String> response = httpClient.send(request, responseBodyHandler);
            String body = response.body();
            String[] lines = body.split("\n");
            String line = lines[1];
            String doubleQuotationMark = "\"";
            String priceText = line.substring(line.indexOf(doubleQuotationMark) + 1, line.lastIndexOf(doubleQuotationMark)).split(",")[0];
            price = Double.parseDouble(priceText);
        } catch (Exception e) {
            log.error("获取布伦特原油实时价格失败，请手动尝试！");
            // TODO 获取布伦特原油实时价格失败处理机制，发邮件或短信给管理员
        }
        return price;
    }

}
